package Main;

/**
 *
 * @author hell
 */

import java.io.*;

import Network.*;
import Control.*;
import GameControl.*;

// Just for testing.
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import net.percederberg.tetris.Game;

public class Main {
    /**
     * @param args the command line arguments
     */
    
    // Temporal, should probably be deleted unless we want to hexdump all data.
/**
* Convert a byte[] array to readable string format. This makes the "hex"
readable!
* @return result String buffer in String format 
* @param in byte[] buffer to convert to string format
*/
public static String byteArrayToHexString(byte in[]) {
    byte ch = 0x00;
    int i = 0; 
    if (in == null || in.length <= 0)
        return null;
    String pseudo[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
    StringBuffer out = new StringBuffer(in.length * 2);
    while (i < in.length) {
        ch = (byte) (in[i] & 0xF0); // Strip off high nibble
        ch = (byte) (ch >>> 4);     // shift the bits down
        ch = (byte) (ch & 0x0F);    // must do this is high order bit is on!
        out.append(pseudo[ (int) ch]); // convert the nibble to a String Character
        ch = (byte) (in[i] & 0x0F); // Strip off low nibble 
        out.append(pseudo[ (int) ch]); // convert the nibble to a String Character
        i++;
    }
    String rslt = new String(out);
    return rslt;
}        
    
    static int DebugLevel = 0; // Minimal level of debug message to be shown.
    // Should have probably made constants for these.
    /**
     * Levels:
     *  9: critical errors.
     *   (Die with supplied message?)
     *  8: important errors.
     *   (Might as well send them as message to user interface instead of console.)
     *  7: ? Network errors (currently: receiving of unknown packet, what might indicate network problems); 
     *  4: some controller messages. They should be changed, probably.
     *  3: Data on internal processings, like creating of objects, sending packets and so on.
     *  etc.
     */
    public static void PrintDebug(int level, String message){
        if (level >= Main.DebugLevel) System.err.println(message);
    }
    
    public static void main(String[] args) throws Exception {
        
        // Initialize networklayer options:
        String MGroup = "224.0.0.99";  // *? Get it from user/configuration?
        int MPort = 23932; // Same here.
        int TTL = 4;
        NetworkLayer.InitSocket(MGroup,MPort, TTL);
        NetworkLayer listener = new NetworkLayer();

        // Add frame window listener
        GameControl.gameFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        java.util.Random rndgen = new java.util.Random();
        Controller.selfID = "GUID."+ // One of ways to get uniqye SelfID
          Long.toHexString(System.currentTimeMillis()).toUpperCase()+ // Current time
          "."+
          Integer.toHexString(rndgen.nextInt()).toUpperCase()+ // Some random number
          ".";
        GameControl.chatframe.setVisible(true);
        GameControl.ChatMessage("------- Your own id: "+Controller.selfID+" -------\n"); // Mostly for testing, should be deleted later

        GameControl.gameFrame.add(GameControl.game.getComponent());
        GameControl.gameFrame.pack();
        GameControl.gameFrame.setVisible(true);

        // Run networklayer thread:
        new Thread(listener).start();
        // *! Still some time for receiving non-InitReply even before initialization.
        NetworkProtocol.InitStateRequest();

    }
}
